//#include "stdafx.h"
#include <windows.h>
#include <Wincrypt.h>
//#include <stdio.h>
//#include <string.h>
//#include <tchar.h>

//in Win CE file1 = "\\Windows\\macs.dat" file2 = "\\Windows\\macs.sign"

//#define CSP_ID TEXT("{59651573-4967-4411-9B5B-239B0BD4383A}")
#define CSP_ID NULL

HLOCAL LoadData (TCHAR* fileName, DWORD *bufferLen)
{
	BYTE* buffer = NULL;
	HLOCAL hMem;
	HANDLE hFile = CreateFile( fileName, GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

	if ( hFile )
	{
		*bufferLen = SetFilePointer(hFile, 0,0, FILE_END);
		if ( *bufferLen != INVALID_SET_FILE_POINTER )
		{
			hMem = LocalAlloc(LMEM_FIXED,sizeof(BYTE)*(*bufferLen));
			buffer = LocalLock(hMem);
			SetFilePointer(hFile, 0,0, FILE_BEGIN);

			ReadFile(hFile, buffer, *bufferLen, bufferLen, NULL);
			
			LocalUnlock(hMem);
		}
		CloseHandle(hFile);
	}

	return hMem;
}

int CreateCryptoProvider( HCRYPTPROV* phCryptProv )
{
	// === Create CCP ===================
	if ( *phCryptProv )
	{
		CryptReleaseContext( *phCryptProv, 0 );
	}

	if (!CryptAcquireContext( phCryptProv, CSP_ID, MS_DEF_PROV, PROV_RSA_FULL, 0) )
	{ 
		if (!CryptAcquireContext( phCryptProv, CSP_ID, MS_DEF_PROV, 
									PROV_RSA_FULL,	CRYPT_NEWKEYSET) )
		{
			return -1;
		}
	}

	return 0;
}

int CreateCryptoKey( HCRYPTPROV hCryptProv, HCRYPTKEY* hKey )
{
	DWORD keySize = 84;
	BYTE  keyBlob[84] = {6,2,0,0,0,36,0,0,82,83,65,49,0,2,0,0,1,0,1,0,169,28,35,78,60,115,175,158,31,65,129,153,197,149,33,19,205,97,86,127,7,138,187,89,104,51,49,88,60,239,18,76,74,173,104,160,139,139,39,225,185,218,237,155,147,5,113,21,188,59,4,79,210,30,98,162,90,5,174,236,84,98,49,179};
	
	if ( !CryptImportKey( hCryptProv, keyBlob, keySize, 0, 0, hKey))
	{
		return -1;
	}

	return 0;
}


int VerifyBuffer( HCRYPTPROV hCryptProv, 
				  HCRYPTKEY hPubKey, 
				  BYTE* buffer, DWORD bufferSize, 
			      BYTE* sign  , DWORD signSize )
{
	int res = -1;
	HCRYPTHASH hHash;

	if ( CryptCreateHash( hCryptProv, CALG_SHA1, 0, 0, &hHash) ==  TRUE) 
	{
		if ( CryptHashData( hHash, buffer, bufferSize, 0) == TRUE ) 
		{
			if ( CryptVerifySignature( hHash, sign, signSize, hPubKey, NULL, 0 ) == TRUE ) 
			{
				res = 0;
			} 
		}
	} 

	if (hHash) CryptDestroyHash(hHash);

	return res;
}


BOOL CheckSign( TCHAR *file1, TCHAR *file2)
{
	HCRYPTPROV hCryptProv = 0;
	HCRYPTKEY  hKey       = 0;
	BOOL res = FALSE;

	if ( CreateCryptoProvider( &hCryptProv ) == 0 )
	{
		if ( CreateCryptoKey( hCryptProv, &hKey ) == 0)
		{
			HLOCAL hBuffer;
			BYTE*  buffer;
			DWORD  bufferSize;
			
			hBuffer = LoadData(file1, &bufferSize);
			buffer = LocalLock(hBuffer);

			if ( buffer )
			{
				HLOCAL hSign;
				BYTE*  sign;
				DWORD signSize;

				hSign = LoadData(file2, &signSize);
				sign = LocalLock(hSign);

				if ( sign )
				{
					if ( VerifyBuffer( hCryptProv, hKey,
									   buffer, bufferSize,    
									   sign  , signSize  ) == 0)
					{
						res =  TRUE;
					}

					LocalUnlock(hSign);
					LocalFree(hSign);
				}

				LocalUnlock(hBuffer);
				LocalFree(hBuffer);
			}
		}
	}

	if ( hKey       ) CryptDestroyKey    ( hKey );
	if ( hCryptProv ) CryptReleaseContext(hCryptProv, 0);

	return res;
}

